package com.example.rbac.config;

import com.example.rbac.mapper.TestMapper;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.*;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;

public class MapperImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
    private ResourceLoader resourceLoader;

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MyScan.class.getName()));

        MyClassPathBeanDefinitionScanner scanner = new MyClassPathBeanDefinitionScanner(registry);
        if (annoAttrs != null) {
            if (this.resourceLoader != null) {
                scanner.setResourceLoader(this.resourceLoader);
            }
            String value = (String)annoAttrs.get("value");
            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MyMapper.class);
            GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
            definition.setBeanClass(MapperFactory.class);
            ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
            constructorArgumentValues.addIndexedArgumentValue(0, TestMapper.class);
            constructorArgumentValues.addIndexedArgumentValue(1, new Handle());
            definition.setConstructorArgumentValues(constructorArgumentValues);

            registry.registerBeanDefinition("myMapper", definition);

            scanner.addIncludeFilter(new AnnotationTypeFilter(MyMapper.class));
            scanner.setResourcePattern("*.class");
            scanner.doScan(value);
            GenericApplicationContext context = new GenericApplicationContext();
            String[] beanDefinitionNames = context.getBeanDefinitionNames();
            for (String beanDefinitionName : beanDefinitionNames) {
                System.out.println(beanDefinitionName);
            }

            boolean myMapper = registry.containsBeanDefinition("myMapper");
            System.out.println(myMapper);
        }
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
}
